import copy
import sys

from PyQt5 import QtGui, QtCore
from PyQt5.QtWidgets import QApplication, QWidget, QLabel
from PyQt5.QtGui import QCursor, QImage
from PyQt5.QtCore import Qt, QSize
import numpy as np
import cv2
from imageManager import *

QIMG_MAX_SIZE = 6553
QIMG_MIN_SIZE = 8


class CenterView(QWidget):
    zone_signal = QtCore.pyqtSignal(tuple)
    show_message = QtCore.pyqtSignal(str)

    def __init__(self, parent=None):
        super(CenterView, self).__init__(parent)
        self.imgLabel = QLabel('Hello World', self)
        self.imgLabel.setAlignment(Qt.AlignCenter)
        self.imgLabel.setScaledContents(True)
        self.imgLabel.setAutoFillBackground(True)
        self.imgLabel.resize(self.size())

        self.setMouseTracking(True)  # 设置鼠标移动跟踪是否有效
        self.imgLabel.setMouseTracking(True)
        self.mouse_mv_y = ""
        self.mouse_mv_x = ""
        self.last_x = ""
        self.last_y = ""
        self.right_flag = False
        self.qimg: QImage = None
        self.img_w = 0
        self.img_h = 0
        self.resize_point = 10
        self.label_x = 0  # label当前坐标
        self.label_y = 0
        self.qimg_w = 0
        self.qimg_h = 0
        self.zone_x0 = 0
        self.zone_y0 = 0
        self.zone_x1 = 0
        self.zone_y1 = 0

    def qimage2mat(self, qimg: QImage):
        if qimg is None:
            return None
        ptr = qimg.constBits()
        ptr.setsize(qimg.byteCount())
        mat = np.array(ptr).reshape(qimg.height(), qimg.width(), 4)  # 注意这地方通道数一定要填4，否则出错
        return mat

    def setImgSize(self, a0: QSize):
        self.img_w = a0.width()
        self.img_h = a0.height()
        self.imgLabel.resize(a0)

    def updateWindowSize(self, size):
        self.resize(size)
        self.imgLabel.resize(self.size())

    def getImageLabelSize(self):
        return self.imgLabel.size()

    def updateImageLabel(self, qimg):
        self.qimg = qimg
        self.qimg_w = qimg.width()
        self.qimg_h = qimg.height()
        w = int(self.imgLabel.width())
        h = int(self.imgLabel.height())
        self.imgLabel.setPixmap(QtGui.QPixmap.fromImage(qimg.scaled(w, h)))

    def mousePressEvent(self, event):  # 鼠标键按下时调用(任意一个键,按一下调一次)，这些方法是许多控件自带的，这里来自于QWidget。
        # self.label.setText('鼠标键按下了')
        n = event.button()  # 用来判断是哪个鼠标健触发了事件【返回值：0  1  2  4】
        if n == QtCore.Qt.LeftButton:
            self.zone_x0 = event.x()  # 返回鼠标相对于窗口的x轴坐标
            self.zone_y0 = event.y()  # 返回鼠标相对于窗口的y轴坐标
        elif n == QtCore.Qt.RightButton:
            self.right_flag = True

        '''
        QtCore.Qt.NoButton - 0 - 没有按下鼠标键
        QtCore.Qt.LeftButton -1 -按下鼠标左键
        QtCore.Qt.RightButton -2 -按下鼠标右键
        QtCore.Qt.Mion 或 QtCore.Qt.MiddleButton -4 -按下鼠标中键
        '''
        nn = event.buttons()  # 返回前面所列枚举值的组合，用于判断同时按下了哪些键【不知怎么判断】  <PyQt5.QtCore.Qt.MouseButtons object at 0x0000003326982F98>

    def mouseReleaseEvent(self, event):
        n = event.button()  # 用来判断是哪个鼠标健触发了事件【返回值：0  1  2  4】
        if n == QtCore.Qt.LeftButton:
            self.zone_x1 = event.x()
            self.zone_y1 = event.y()
            x = int(self.zone_x0 * self.qimg_w / self.img_w)
            y = int(self.zone_y0 * self.qimg_h / self.img_h)
            w = int(self.zone_x1 * self.qimg_w / self.img_w) - int(self.zone_x0 * self.qimg_w / self.img_w)
            h = int(self.zone_y1 * self.qimg_h / self.img_h) - int(self.zone_y0 * self.qimg_h / self.img_h)
            self.zone_signal.emit((x, y, w, h))

        self.right_flag = False
        self.mouse_mv_y = ""
        self.mouse_mv_x = ""
        self.last_x = ""
        self.last_y = ""

    def mouseMoveEvent(self, event):  # 鼠标移动事件
        ret = self.hasMouseTracking()  # 返回鼠标MouseTracking的状态
        if not ret:
            return
        # self.label1.setText('鼠标移动了:%s' % ret)
        x = event.x()  # 返回鼠标相对于窗口的x轴坐标
        y = event.y()  # 返回鼠标相对于窗口的y轴坐标
        self.show_message.emit('w*h=%sx%s,(x,y)=(%s,%s)' % (
        self.img_w, self.img_h, int(x * self.qimg_w / self.img_w), int(y * self.qimg_h / self.img_h)))
        xy = event.pos()  # 返回鼠标坐标 ，QPoint(463, 0) 相对于控件  【用xy.x()  xy.y()提取值】
        # print(xy)
        s = event.localPos()  # 返回鼠标坐标  相对于控件   QPointF(2.0, 2.0)
        s = self.mapToGlobal(xy)  # 将窗口坐标转换成屏幕坐标.属于QWidget类的方法；参数类型QPoint
        # self.label3.setText('鼠标x坐标：%s  ,鼠标y坐标：%s' % (xy.x(), xy.y()))
        xy1 = event.globalPos()  # 返回鼠标相对于屏幕的坐标。PyQt5.QtCore.QPoint(1096, 37)【用xy1.x()  xy1.y()提取值】
        # print(xy1)
        s1 = self.mapFromGlobal(xy1)  # 将屏幕坐标转换成窗口坐标.属于QWidget类的方法；参数类型QPoint
        # mapToParent(QPoint) - 将窗口坐标转换成父窗口坐标。如果没有父窗口，则相当于mapToGlobal (QPoint)
        # mapFromParent(QPoint) - 将父窗口坐标转换成窗口坐标。如果没有父窗口，则相当于mapFromGlobal(QPoint)
        # mapTo (QWidget, QPoint) - 将窗口坐标转换成 QWidget父窗口坐标
        px = event.globalX()  # 返回相对于屏幕的x坐标
        py = event.globalY()  # 返回相对于屏幕的y坐标
        s = event.windowPos()  # 相对于窗口的坐标(保留一位小数)，PyQt5.QtCore.QPointF(481.0, 1.0)【用s.x()  s.y()提取值】
        p = event.screenPos()  # 相对于屏幕的坐标(保留一位小数).PyQt5.QtCore.QPointF(476.0, 49.0)【用p.x()  p.y()提取值】
        t = event.timestamp()  # 返回事件发生的时间。【以程序运行开始计时，以毫秒为单位】

        if self.right_flag:  # 鼠标右击
            x1 = event.x()
            y1 = event.y()
            if self.mouse_mv_x != "" and self.mouse_mv_y != "":
                self.label_x = self.label_x + (x1 - self.mouse_mv_x)
                self.label_y = self.label_y + (y1 - self.mouse_mv_y)
            self.mouse_mv_x = x1
            self.mouse_mv_y = y1
            self.imgLabel.setGeometry(self.label_x, self.label_y, self.img_w, self.img_h)

    def mouseDoubleClickEvent(self, event):  # 鼠标双击时调用
        print("mouseDoubleClickEvent")
        # self.label1.setText('双击了鼠标')
        '''
        双击时的事件顺序如下:
        MouseButtonPress
        MouseButtonRelease
        MouseButtonDblClick
        MouseButtonPress
        MouseButtonRelease
        QApplicaption类的setDoubleClickInterval( )方法可设置双击的时间间隔；doubleClickInterval( )方法返回双击的时间间隔。
        '''

    def enterEvent(self, event):  # 鼠标移进时调用
        # print('鼠标移进窗口了')
        self.setCursor(Qt.CrossCursor)  # 设置鼠标形状。
        # 需要from PyQt5.QtGui import QCursor,from PyQt5.QtCore import Qt
        # 鼠标形状对照图见下方
        # self.unsetCursor()   #鼠标恢复系统默认

    def leaveEvent(self, event):  # 鼠标移出时调用
        # print('鼠标移出窗口了'
        pass

    def wheelEvent(self, event):  # 滚轮滚动时调用。event是一个QWheelEvent对象
        angle = event.angleDelta() / 8

        angleY = angle.y()
        if angleY > 0:
            if 1 <= self.resize_point <= 19:
                self.resize_point = 11
        elif angleY < 0:
            if 2 <= self.resize_point <= 20:
                self.resize_point = 9

        w = int(self.img_w * self.resize_point / 10)
        h = int(self.img_h * self.resize_point / 10)
        if QIMG_MIN_SIZE < w < QIMG_MAX_SIZE and QIMG_MIN_SIZE < h < QIMG_MAX_SIZE:
            self.imgLabel.setGeometry(QtCore.QRect(self.label_x,
                                                   self.label_y,
                                                   w, h))

            self.img_w = w
            self.img_h = h
            self.show_message.emit('current size:w*h=%sx%s' % (self.img_w, self.img_h))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = CenterView()
    demo.show()
    sys.exit(app.exec())
